package com.xiaobaibai.security.units;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xiaobaibai.entity.UserAdmin;
import com.xiaobaibai.security.common.TokenCommon;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class TokenService {

    @Autowired
    private TokenCommon tokenCommon;

    public String getToken(UserAdmin userAdmin){
        Date date = new Date();
        String token = JWT.create()
                //下面这
                .withAudience(userAdmin.getUsername())//发给谁的签名
                .withClaim(TokenCommon.TokenRole,"ADMIN")
                .withClaim(TokenCommon.TokenName,userAdmin.getUsername())
//                .withClaim("还可以自定义key","还可以自定义value")
//                .withIssuer("xiaobaibai")//谁发放的签名
//                .withSubject("subject")//签名的主题
//                .withNotBefore(date)//签名的生效时间
                .withIssuedAt(date)//签名的生成时间
                .withExpiresAt(DateUtils.addHours(date, 24))//签名失效时间
//                .withJWTId(UUID.randomUUID().toString())//jwt的编号,相当于一个jwt的id
                .sign(Algorithm.HMAC256(TokenCommon.TokenAssert));//到时解密用的密匙(只能服务器知道)
        return token;
    }

    public Map<String,Object> checkingToken(String token){

        Map map=new HashMap<>(4);

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TokenCommon.TokenAssert)).build();

        try {
            DecodedJWT verify = jwtVerifier.verify(token);
            map.put(TokenCommon.TokenResult,true);
            map.put(TokenCommon.TokenRole,verify.getClaim(TokenCommon.TokenRole).asString());
            map.put(TokenCommon.TokenVerify,verify);
        }catch (Exception e){
            map.put(TokenCommon.TokenResult,false);
            log.info("token错误");
        }

        return map;
    }

    //刷新token
    public String refreshToken( Authentication authentication){

        DecodedJWT verify = (DecodedJWT) authentication.getPrincipal();

        Date expiresAt = verify.getExpiresAt();//获取失效时间

        //假如还有12个小时就过期了,就刷新一下
        Date date = DateUtils.addHours(new Date(), 12);

        if(expiresAt.before(date)){//失效时间在(现在时间后的一个小时)之前

            //换一下加密盐
            tokenCommon.switchSalt();

            UserAdmin userAdmin=new UserAdmin();
            userAdmin.setUsername(authentication.getName());

            return getToken(userAdmin);
        }
        return null;
    }

}
